// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Segment_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Segment_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Segment_2_doc[] =
{
"An object s of the data type Segment_2 is a directed straight line segment in the two-dimensional Euclidean plane RxR,\n i.e. a straight line segment [p,q] connecting two points p,q in RxR.\nThe segment is topologically closed, i.e. the end points belong to it.\nPoint p is called the source and q is called the target of s. \nThe length of s is the Euclidean distance between p and q. Note that there is only a function to compute the square of the length,\nbecause otherwise we had to perform a square root operation which is not defined for all number types, which is expensive, and may not be exact..\n"\
"For more details see a C++ doc:\nhttp://www.cgal.org/Manual/doc_html/cgal_manual/Kernel_23_ref/Class_Segment_2.html\n\n"\
"Creation:\n s = Segment_2( Point_2 p, Point_2 q)\nintroduces a segment s with source p and target q.\n The segment is directed from the source towards the target.\n",
"source(self) -> Point_2\nreturns the source of s.\n",
"target(self) -> Point_2\nreturns the target of s.\n",
"min(self) ->  Point_2\nreturns the point of s with lexicographically smallest coordinate.\n",
"max(self) ->  Point_2\nreturns the point of Segment with lexicographically largest coordinate.\n",
"vertex(self,i) -> Point_2\nreturns source or target of s: vertex(0) returns the source of s, vertex(1) returns the target of s.\nThe parameter i is taken modulo 2, which gives easy access to the other vertex.\n",
"point(self) -> returns vertex(i).\n",
"has_on(self,Point_2 p) -> bool\nA point p is on s, iff it is equal to the source or target of s, or if it is in the interior of s.\n",
"collinear_has_on(self,Point_2) -> bool\nchecks if point p is on segment s. This function is faster than function has_on().\nPrecondition: p is on the supporting line of s.",
"squared_length(self) -> double\nreturns the squared length of s.",
"is_degenerate(self) -> bool\nsegment s is degenerate, if source and target are equal. \n",
"bbox(self) -> Bbox_2\nreturns a bounding box containing s.\n",
"direction(self) -> Direction_2\nreturns the direction from source to target of s.\n",
"to_vector(self) -> Vector_2\nreturns the vector s.target() - s.source(). \n",
"supporting_line(self) -> Line_2\nreturns the line l passing through s.\nLine l has the same orientation as segment s.\n",
"opposite(self) -> Segment_2\nreturns a segment with source and target point interchanged.\n",
"transform(self,Aff_transformation_2 t) -> Segment_2\nreturns the segment obtained by applying t on the source and the target of s.\n",
"s[i] -> Point_2\nreturns vertex(i)\n"
};

template<class Segment_2>
boost::python::str py_repr_Segment_2(const Segment_2& s )
{
	using namespace boost::python;
	return str("Segment_2("+ str(s.source()) +","+ str(s.target()) +")" );
}

template<class kernel>
void Py_Segment_2()
{
	typedef typename kernel::Point_2 					Point_2;
	typedef typename kernel::Segment_2 					Segment_2;
 	typedef typename kernel::Vector_2 					Vector_2;
 	typedef typename kernel::Direction_2 					Direction_2;
 	typedef typename kernel::Line_2 					Line_2;
  	typedef typename kernel::Ray_2 					        Ray_2;
 	typedef typename kernel::Triangle_2 					Triangle_2;
	typedef typename kernel::Iso_rectangle_2 				Iso_rectangle_2;
	typedef typename kernel::Circle_2 				      	Circle_2;
	typedef typename kernel::Aff_transformation_2 				Aff_transformation_2;
	typedef typename kernel::FT 						FT;
	typedef typename kernel::RT						RT;

	using namespace boost::python;

	class_<Segment_2>("Segment_2", Segment_2_doc[0], init<>())
        .def(init< const Segment_2& >())
        .def(init< const Point_2&, const Point_2& >())
#if CGAL_VERSION_NR < 1030301000
        .def("source", &Segment_2::source, by_cref(), Segment_2_doc[1])
        .def("target", &Segment_2::target, by_cref(), Segment_2_doc[2])
        .def("start", &Segment_2::start, by_cref())
        .def("end", &Segment_2::end, by_cref())
        .def("min", &Segment_2::min, by_cref(), Segment_2_doc[3])
        .def("max", &Segment_2::max, by_cref(), Segment_2_doc[4])
        .def("vertex", &Segment_2::vertex, by_cref(), Segment_2_doc[5])
        .def("point", &Segment_2::point, by_cref(), Segment_2_doc[6])
#else
        .def("source", &Segment_2::source, typename Value_or_cref<typename kernel::Construct_source_2, Segment_2 > ::type(), Segment_2_doc[1])
        .def("target", &Segment_2::target, typename Value_or_cref<typename kernel::Construct_target_2, Segment_2 > ::type(), Segment_2_doc[2])
        .def("start", &Segment_2::start, typename Value_or_cref<typename kernel::Construct_source_2, Segment_2 > ::type())
        .def("end", &Segment_2::end, typename Value_or_cref<typename kernel::Construct_target_2, Segment_2 > ::type())
        .def("min", &Segment_2::min, typename Value_or_cref<typename kernel::Construct_min_vertex_2, Segment_2 > ::type(), Segment_2_doc[3])
        .def("max", &Segment_2::max, typename Value_or_cref<typename kernel::Construct_max_vertex_2, Segment_2 > ::type(), Segment_2_doc[4])
        .def("vertex", &Segment_2::vertex, typename Value_or_cref<typename kernel::Construct_vertex_2, Segment_2, int > ::type(), Segment_2_doc[5])
        .def("point", &Segment_2::point, typename Value_or_cref<typename kernel::Construct_vertex_2, Segment_2, int > ::type(), Segment_2_doc[6])
#endif
        .def("is_horizontal", &Segment_2::is_horizontal)
        .def("is_vertical", &Segment_2::is_vertical)
        .def("has_on", &Segment_2::has_on, Segment_2_doc[7])
        .def("collinear_has_on", &Segment_2::collinear_has_on, Segment_2_doc[8])
        .def("squared_length", &Segment_2::squared_length, Segment_2_doc[9])
        .def("is_degenerate", &Segment_2::is_degenerate, Segment_2_doc[10])
        .def("bbox", &Segment_2::bbox, Segment_2_doc[11])
        .def("direction", &Segment_2::direction, Segment_2_doc[12])
        .def("to_vector", &Segment_2::to_vector, Segment_2_doc[13])
        .def("supporting_line", &Segment_2::supporting_line, Segment_2_doc[14])
        .def("opposite", &Segment_2::opposite, Segment_2_doc[15])
        .def("transform", &Segment_2::transform, Segment_2_doc[16])
#if CGAL_VERSION_NR < 1030301000
        .def("__getitem__", &Segment_2::operator [], by_cref(), Segment_2_doc[17])
#else
        .def("__getitem__", &Segment_2::operator [], typename Value_or_cref<typename kernel::Construct_vertex_2, Segment_2, int > ::type(), Segment_2_doc[17])
#endif
        .def("__repr__", &py_repr_Segment_2<Segment_2>)

	.def( self == self )
        .def( self != self )
    ;
}

void export_Segment_2()
{
	Py_Segment_2<K>();
}
